#ifndef _POINT_H
#define _POINT_H

#include  <cmath>
#include <iostream>

class Point{
public:

	Point();
	virtual ~Point();
	
	Point(double newx, double newy, double newz);
	Point(int newx, int newy, int newz);
	Point(const Point &newpoint);

	double& x() {return _x; };
	double& y() {return _y; };
	double& z() {return _z; };
        
    Point operator-() const;
        
	void operator += (const Point &other);
	void operator /= (const int divisor);
	void operator /= (const double divisor);
	void operator *= (const int factor);
	void operator *= (const double factor);
	
	Point& operator=(const Point &other);
	Point  operator+(const Point &other);
	Point  operator-(const Point &other);
	Point  operator-(const Point &other) const;

	Point  operator/(const double divisor);
	Point  operator*(const double factor);

	inline bool operator != (const Point &other) { return ( (_x!=other._x ) || (_y!=other._y) || (_z != other._z)); };
	inline double dot(Point Other){ return _x*Other._x+_y*Other._y+_z*Other._z; };				
	inline Point cross(Point  Other){	return Point(_y*Other._z-Other._y*_z, _z*Other._x-_x*Other._z, _x*Other._y-_y*Other._x); };
	inline double abs(){ return sqrt(_x*_x+_y*_y+_z*_z); };
        
        int getIndex(int sx, int sy) { return ((int)_z)*sx*sy + ((int)_y)*sx + (int)_x; };

        void normalize();
        
	static Point TransMatMultiply( double* transMat, Point inPoint);

	friend std::ostream & operator <<( std::ostream &outs, const Point &a) {
 	  outs << "(" << a._x << "," << a._y << "," << a._z << ")" << std::endl; 
	  return outs; 
	}; 


protected:
	double _x;
	double _y;
	double _z;
};

#endif // POINT_H
